home *** CD-ROM | disk | FTP | other *** search
- /*
- * AttackDude.c - Fix autoremounter behavior.
- *
- * Mark D. Rustad 93/06/16.
- *
- * This extension (hack) changes the behavior of autoremounter
- * to never send broadcast echo packets (imagine what that does
- * to large ethernets or token rings). It is called “Dude NOT!”
- * because all the trouble is caused by the 'dude' Gestalt selector
- * function.
- *
- * Installation of this extension will tend to prevent autoremounter
- * from remounting volumes on very small networks when you plug into
- * the network after coming out of sleep. Of course, you should
- * always connect the network BEFORE coming out of sleep to ensure
- * that a unique AppleTalk address is acquired... So, if you never
- * use a large network and like to plug a running maching into active
- * networks, this hack is not for you.
- *
- * This hack also demonstrates the creation of a stand-alone code
- * resource with it’s own A5 world and no assembly and no _datainit
- * junk. Of course, I do need to use GCC to do this and a couple inlines,
- * but I like it, because compilers can generate smaller, faster code
- * if you use A5 worlds rather than passing global variable pointers
- * around all over (I wish I had discovered this technique years ago).
- * You can use the same technique with MPW C if you link with one tiny
- * assembly routine (provided in the comments later).
- *
- * This hack turned out so simple I didn’t even need any globals, so in
- * this case things could be simplified by NOT setting up the A5 world,
- * but then this hack couldn’t demonstrate the efficient, convenient use
- * of A5 globals in a stand-alone code resource.
- */
-
- #define SystemSixOrLater 1
-
- #include <Types.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <GestaltEqu.h>
-
- /* The following inline swaps A5 values */
-
- #pragma parameter __D0 SwapA5 (__D0)
- void *SwapA5(void *) = {0xC18D}; /* Exg D0, A5 */
-
- long *GetA5(void) = 0x200D;
-
- /* Forward declarations */
-
- static int GetInitSize(long *p);
- static void _A5Init(void);
- static void FixRemounter(void);
-
-
- void Init(void)
- {
- long *p = (long *)&_A5Init;
- char *gptr;
- long *oldA5;
-
- if (GetInitSize(p)) /* This verifies that no globals were initialized non-zero */
- {
- DebugStr((unsigned char *)"\pInit data present");
- return;
- }
-
- /* Allocate space for globals */
-
- if ((gptr = (char *)NewPtrSysClear(*p + 32)) == 0)
- return;
-
- oldA5 = SwapA5(gptr + *p); /* Set up A5 for globals */
- // *GetA5() = *oldA5; /* Uncomment this line if you want to inherit qd globals */
-
- /* Do something */
- FixRemounter();
-
- SwapA5(oldA5); /* Restore A5 */
- return;
- }
-
-
- /*
- * GetInitSize - Return size of initialization records.
- *
- * This function is required simply for a successful build
- * with gcc since it generates code that will fail to link.
- * This is due to the fact that the pointer is really pointing
- * into code space. Adding this function prevented a gcc
- * transformation that resulted in unlinkable code.
- */
-
- static int GetInitSize(long *p)
- {
- return p[2];
- }
-
-
- /*
- * _A5Init - Dummy function to permit global data declarations.
- *
- * Using a C function this way only works when compiled using GCC under
- * MPW. If using MPW C, a tiny assembly equivalent, as follows, will
- * work:
- * Proc
- * Export _A5Init
- * _A5Init DC.W 0
- * EndProc
- * End
- */
-
- void _A5Init(void)
- {
- }
-
-
- /* Here is my global, even though I don’t really need it */
-
- static ProcPtr OrigDudeFunc;
-
-
- /*
- * FixRemounter - Fix Autoremounter.
- */
-
- static void FixRemounter(void)
- {
- OSErr result;
- pascal OSErr MyDudeFunc(long, long *);
-
- result = ReplaceGestalt('dude', (ProcPtr)MyDudeFunc, &OrigDudeFunc);
- switch (result)
- {
- case gestaltUndefSelectorErr:
- return;
-
- case gestaltLocationErr:
- case gestaltUnknownErr:
- default:
- return;
-
- case noErr:
- break;
- }
-
- /* Replaced dude (hopefully before it had been invoked) */
-
- {
- Handle hdl;
-
- hdl = RecoverHandle((void *)&Init);
- DetachResource(hdl);
- }
- }
-
-
- /*
- * MyDudeFunc - My replacement for the 'dude' gestalt routine.
- */
-
- pascal OSErr MyDudeFunc(long sel, long *result)
- {
- OSErr err;
-
- err = Gestalt('atlk', result);
- *result = (*result == 0) + 16;
- return err;
- }
-